/**
 * Copyright &copy; 2012-2016 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved.
 */
package com.thinkgem.jeesite.modules.ins.service;

import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.script.Bindings;
import javax.script.Compilable;
import javax.script.CompiledScript;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.servlet.http.HttpServletRequest;

import org.apache.poi.ss.usermodel.Row;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.thinkgem.jeesite.common.mapper.JsonMapper;
import com.thinkgem.jeesite.common.persistence.Page;
import com.thinkgem.jeesite.common.service.CrudService;
import com.thinkgem.jeesite.common.utils.DocUtil;
import com.thinkgem.jeesite.common.utils.MailUtil;
import com.thinkgem.jeesite.common.utils.MathUtil;
import com.thinkgem.jeesite.common.utils.StringUtils;
import com.thinkgem.jeesite.common.utils.WordToPDF;
import com.thinkgem.jeesite.common.utils.excel.ImportExcel;
import com.thinkgem.jeesite.modules.ins.dao.InsDataDao;
import com.thinkgem.jeesite.modules.ins.dao.InsDataLinkDao;
import com.thinkgem.jeesite.modules.ins.dao.InsFieldDao;
import com.thinkgem.jeesite.modules.ins.entity.InsData;
import com.thinkgem.jeesite.modules.ins.entity.InsDataLink;
import com.thinkgem.jeesite.modules.ins.entity.InsField;
import com.thinkgem.jeesite.modules.ins.entity.InsLog;
import com.thinkgem.jeesite.modules.ins.entity.InsTable;
import com.thinkgem.jeesite.modules.ins.entity.InsTemplate;
import com.thinkgem.jeesite.modules.sys.entity.User;
import com.thinkgem.jeesite.modules.sys.service.SystemService;

/**
 * 检验报告书-分类Service
 * @author fanqinglong
 * @version 2017-11-20
 */
@Service
@Transactional(readOnly = true)
public class InsDataService extends CrudService<InsDataDao, InsData> {
	@Autowired
	private InsDataLinkDao insDataLinkDao;
	@Autowired
	private InsFieldDao insFieldDao;
	@Autowired
	private InsLogService insLogService;
	@Autowired
	private InsTemplateService insTemplateService;
	@Autowired
	private InsTableService insTableService;
	@Autowired
	private SystemService systemService;
	
	public InsData get(String id) {
		InsData data = super.get(id);
		List<InsDataLink> dataLinks = insDataLinkDao.getByDataId(id);
		//添加新添的field列表
		List<InsField> newFields = insFieldDao.getNewField(data);
		for (InsField insField : newFields) {
			InsDataLink dataLink = new InsDataLink();
			dataLink.setField(insField);
			dataLink.setTable(data.getTable());
			dataLinks.add(dataLink);
		}
		sortList(dataLinks);
		for (InsDataLink insDataLink : dataLinks) {
			InsField field = insDataLink.getField();
			if ("1".equals(field.getPreInput())) {
				String[] values = field.getPreValues().split(";+|；+");
				field.setInsValueList(Arrays.asList(values));
			}
		}
		data.setDatas(dataLinks);
		return data;
	}
	
	public List<List<String>> findList(InsData insData,Page<InsData> page,boolean isPage) {
		// 需要分页
		if (isPage) {
			insData.setPage(page);
		}else {
			insData.setIndex("");
		}
		List<InsData> datas = dao.findList(insData);
		List<List<String>> dataList = new ArrayList<>();
		for (int i = 0; i < datas.size(); i++) {
			List<String> valList = new ArrayList<>();
			InsData data = datas.get(i);
			List<InsDataLink> dataLinks = insDataLinkDao.getByDataId(data.getId());
			//添加新添的field列表
			List<InsField> newFields = insFieldDao.getNewField(data);
			for (InsField insField : newFields) {
				InsDataLink dataLink = new InsDataLink();
				dataLink.setField(insField);
				dataLink.setTable(data.getTable());
				dataLinks.add(dataLink);
			}
			sortList(dataLinks);
			for(InsDataLink dataLink : dataLinks){
				valList.add(dataLink.getValue());
			}
			dataList.add(valList);
		}
		return dataList;
	}
	
	@Transactional(isolation = Isolation.DEFAULT,propagation = Propagation.REQUIRED,readOnly = false, rollbackFor = Exception.class)
	public String export(InsData insData,HttpServletRequest request){
		// 获取模板
		InsTemplate param = insData.getTable().getTemplate();
		InsTemplate template = insTemplateService.get(param.getId());
		String src = template.getSrc();
		if (StringUtils.isEmpty(src)) {
			return "error:模板读取错误";
		}
		
		// 获取数据
		Map<String, String> dataMap = getDataMap(insData);
		// 导出
		String url = DocUtil.createDoc(request,src, dataMap,insData.getName());
		if (url.indexOf("error:") <= -1) {
			//记日志
			InsLog insLog = new InsLog(InsLog.MODULE_DATA, InsLog.TYPE_PRINT, insData.getTable(), insData.getId(), JsonMapper.toJsonString(insData));
			insLogService.save(insLog);
		}
		return url;
	}
	@Transactional(isolation = Isolation.DEFAULT,propagation = Propagation.REQUIRED,readOnly = false, rollbackFor = Exception.class)
	public String exportPDF(InsData insData,HttpServletRequest request){
		// 获取模板
		InsTemplate param = insData.getTable().getTemplate();
		InsTemplate template = insTemplateService.get(param.getId());
		String src = template.getSrc();
		if (StringUtils.isEmpty(src)) {
			return "error:模板读取错误";
		}
		
		// 获取数据
		Map<String, String> dataMap = getDataMap(insData);
		// 导出
		String url = DocUtil.createDoc(request,src, dataMap,insData.getName());
		String pdfUrl = "outPDF_"+System.currentTimeMillis()+".pdf";
		if (url.indexOf("error:") <= -1) {
			
			//记日志
			InsLog insLog = new InsLog(InsLog.MODULE_DATA, InsLog.TYPE_PRINT, insData.getTable(), insData.getId(), JsonMapper.toJsonString(insData));
			insLogService.save(insLog);
			return WordToPDF.wordToPdf(request, url, pdfUrl);
		}
		return url;
	}
	
	@Transactional(isolation = Isolation.DEFAULT,propagation = Propagation.REQUIRED,readOnly = false, rollbackFor = Exception.class)
	public String printPDF(InsData insData,HttpServletRequest request){
		// 获取模板
		InsTemplate param = insData.getTable().getTemplate();
		InsTemplate template = insTemplateService.get(param.getId());
		String src = template.getSrc();
		if (StringUtils.isEmpty(src)) {
			return "error:模板读取错误";
		}
		
		// 获取数据
		Map<String, String> dataMap = getDataMap(insData);
		// 导出
		String url = DocUtil.createDoc(request,src, dataMap,insData.getName());
		String result = "error:打印异常";
		if (url.indexOf("error:") <= -1) {
			return WordToPDF.printPdf(url);
		}
		return result;
	}
	
	@Override
	public Page<InsData> findPage(Page<InsData> page, InsData entity) {
		if (null != entity.getDateField() && !StringUtils.isEmpty(entity.getDateField().getId())) {
			InsField dateField = insFieldDao.get(entity.getDateField().getId());
			entity.setDateField(dateField);
			//需要根据日期筛选
			if (!StringUtils.isEmpty(entity.getDateFrom()) || !StringUtils.isEmpty(entity.getDateTo())) {
				entity.getSqlMap().put("dateSQL", getDateSelectSQL(entity));
			}
		}
		entity.setPage(page);
		List<InsData> datas = dao.findList(entity);
		for (int i = 0; i < datas.size(); i++) {
			InsData data = datas.get(i);
			List<InsDataLink> dataLinks = insDataLinkDao.getByDataId(data.getId());
			//添加新添的field列表
			List<InsField> newFields = insFieldDao.getNewField(data);
			for (InsField insField : newFields) {
				InsDataLink dataLink = new InsDataLink();
				dataLink.setField(insField);
				dataLink.setTable(data.getTable());
				dataLinks.add(dataLink);
			}
			sortList(dataLinks);
			data.setDatas(dataLinks);
		}
		page.setList(datas);
		return page;
	}

	@Transactional(isolation = Isolation.DEFAULT,propagation = Propagation.REQUIRED,readOnly = false, rollbackFor = Exception.class)
	public String saveData(InsData insData)throws Exception{
		String result = "success";
		boolean flag = insData.getIsNewRecord();
		InsData oldData = new InsData();
		Map<String, InsData> map = new HashMap<>();
		if (!flag) {
			oldData = get(insData.getId());
			map.put("oldData", oldData);
			map.put("insData", insData);
		}
		super.save(insData);
		//删除原来的datalinks
		insDataLinkDao.deleteByDataId(insData.getId());
		List<InsDataLink> datas = insData.getDatas();
		//获取排序和值的映射，以备替换公式参数
		Map<String, BigDecimal> sortMap = getSortMap(datas);
		//超出数值范围的参数列表
		StringBuffer overRangeFields = new StringBuffer();
		for (InsDataLink insDataLink : datas) {
			insDataLink.preInsert();
			InsField field = insDataLink.getField();
			//针对数字参数
			if ("2".equals(field.getType())) {
				//需要计算
				if (!StringUtils.isEmpty(field.getPreValues())) {
					String caculateResult = caculate(insDataLink.getField().getPreValues(), sortMap);
					if ("存在空数据字段，请仔细检查！".equals(caculateResult)) {
						return caculateResult;
					}
					insDataLink.setValue(caculateResult);
				}
				//校验数值范围
				if ("1".equals(field.getEnableNumberRange()) && validNumberRange(field, insDataLink.getValue())) {
					//设置标记
					insDataLink.setOverRange("1");
					overRangeFields.append(field.getName()+" ");
					
				}else{
					insDataLink.setOverRange("0");
				}
			}
			insDataLink.setData(insData);
			//insDataLink.setValue(StringUtils.replaceHTMLentity(insDataLink.getValue()));
			insDataLinkDao.insert(insDataLink);
		}
		//发送邮件
		if (overRangeFields.length() > 0) {
			//给设置的收件人发送邮件
			InsTable insTable = insData.getTable();
			sendMailToUsers(insTable, overRangeFields.toString());
		}
		//日志添加
		InsLog insLog = new InsLog(InsLog.MODULE_DATA, flag?InsLog.TYPE_WRITE:InsLog.TYPE_SAVE, insData.getTable(), insData.getId(), JsonMapper.toJsonString(flag?insData:map));
		insLogService.save(insLog);
		return result;
	}
	
	@Transactional(isolation = Isolation.DEFAULT,propagation = Propagation.REQUIRED,readOnly = false, rollbackFor = Exception.class)
	public void delete(InsData insData) {
		super.delete(insData);
		//日志添加
		InsLog insLog = new InsLog(InsLog.MODULE_DATA, InsLog.TYPE_DELETE, insData.getTable(), insData.getId(), JsonMapper.toJsonString(insData));
		insLogService.save(insLog);
	}
	
	@Transactional(isolation = Isolation.DEFAULT,propagation = Propagation.REQUIRED,readOnly = false, rollbackFor = Exception.class)
	public String importFile(ImportExcel ei,InsData insData){
		String result = "";
		int sum = 0;
		try {
			List<String> headList = new ArrayList<>();
			InsTable insTable = insTableService.get(insData.getTable().getId());
			//建立参数名称-参数映射
			Map<String, InsField> fieldMap = new HashMap<>();
			for (InsField field : insTable.getInsFieldList()) {
				headList.add(field.getName());
				fieldMap.put(field.getName(), field);
			}
			//得到表头，建立顺序映射
			Row head = ei.getRow(0);
			Map<Integer, String> map = new HashMap<>();
			for (int i = 0; i < ei.getLastCellNum(); i++) {
				map.put(i, ei.getCellValue(head, i).toString());
				if (!headList.contains(ei.getCellValue(head, i).toString())) {
					result = "error:导入失败！表头有误，请仔细检查！";
					return result;
				}
			}
			//数值超过范围的参数集合
			Set<String> fieldSet = new HashSet<>();
			//数值超过范围的数据条数
			int count = 0;
			for (int i = ei.getDataRowNum(); i < ei.getLastDataRowNum(); i++) {
				Row row = ei.getRow(i);
				InsData tempData = new InsData();
				tempData.setTable(insData.getTable());
				save(tempData);
				boolean overRangeFlag = false;
				for (int j = 0; j < ei.getLastCellNum(); j++) {
					//参数名称
					String fieldName = map.get(j);
					InsField field = fieldMap.get(fieldName);
					Object val = ei.getCellValue(row, j);
					InsDataLink insDataLink = new InsDataLink();
					insDataLink.setTable(insData.getTable());
					insDataLink.setField(field);
					insDataLink.setValue(String.valueOf(val));
					insDataLink.setData(tempData);
					//判断是否超出数值范围
					if ("2".equals(field.getType()) 
							&& "1".equals(field.getEnableNumberRange()) 
							&& validNumberRange(field, String.valueOf(val))) {
						insDataLink.setOverRange("1");
						fieldSet.add(fieldName);
						overRangeFlag = true;
					}
					insDataLink.preInsert();
					insDataLinkDao.insert(insDataLink);
				}
				sum++;
				if (overRangeFlag) {
					count++;
				}
			}
			result = "成功导入"+sum+"条数据！";
			//发送超过范围邮件
			if (count > 0) {
				StringBuffer overRangeFields = new StringBuffer();
				for (String fieldName : fieldSet) {
					overRangeFields.append(fieldName+" ");
				}
				//给设置的收件人发送邮件
				sendMailToUsers(insTable, overRangeFields.toString());
			}
		} catch (Exception e) {
			result = "error:导入失败！"+e.getMessage();
		}
		return result;
	}
	
	/**
	 * 校验是否超过数值范围
	 * @param insField
	 * @param value
	 * @return
	 */
	private boolean validNumberRange(InsField insField ,String value){
		String numberFrom = insField.getNumberFrom();
		String numberTo = insField.getNumberTo();
		double val = Double.valueOf(value);
		//起止都为空，直接返回true
		if (StringUtils.isEmpty(numberFrom) && StringUtils.isEmpty(numberTo)) {
			return false;
		}
		if (!StringUtils.isEmpty(numberFrom) && val < Double.valueOf(numberFrom)) {
			return true;
		}
		if (!StringUtils.isEmpty(numberTo) && val > Double.valueOf(numberTo)) {
			return true;
		}
		return false;
	}
	
	private void sortList(List<InsDataLink> list){
		Collections.sort(list,new Comparator<InsDataLink>(){
            public int compare(InsDataLink arg0, InsDataLink arg1) {
                return arg0.getField().getSort().compareTo(arg1.getField().getSort());
            }
        });
	}
	
	private Map<String, String> getDataMap(InsData insData){
		List<InsDataLink> datas = insData.getDatas();
		if (null == datas) {
			return new HashMap<>();
		}
		Map<String, String> dataMap = new HashMap<>();
		for (InsDataLink insDataLink : datas) {
			dataMap.put(insDataLink.getField().getCode(), StringUtils.replaceHTMLentity(insDataLink.getValue()));
		}
		return dataMap;
	}
	
	/**
	 * 根据筛选的日期类型和超始条件生成SQL语句
	 * @param type
	 * @param dateFrom
	 * @param dateTo
	 * @return
	 */
	private String getDateSelectSQL(InsData insData){
		StringBuffer stringBuffer = new StringBuffer();
		stringBuffer.append("    AND a.id in(");
		stringBuffer.append("SELECT ida.id FROM ins_data ida JOIN ins_field ifb ON ida.table_id=ifb.table_id ");
		stringBuffer.append("LEFT JOIN ins_data_link idlc ON ifb.id=idlc.field_id and idlc.data_id=ida.id WHERE ");
		stringBuffer.append("ida.table_id = '"+insData.getTable().getId()+"' ");
		stringBuffer.append("AND ifb.id='"+insData.getDateField().getId()+"'  ");
		if (!StringUtils.isEmpty(insData.getDateFrom())) {
			stringBuffer.append("AND idlc.value >= '"+insData.getDateFrom()+"'");
		}
		if (!StringUtils.isEmpty(insData.getDateTo())) {
			stringBuffer.append("AND idlc.value <= '"+insData.getDateTo()+"'");
		}
		stringBuffer.append(")");
		return stringBuffer.toString();
	}
	
	/**
	 * 根据公式计算出该参数的值
	 * @param script
	 * @param sortMap
	 * @return
	 * @throws ScriptException
	 */
	private String caculate(String script,Map<String, BigDecimal> sortMap) throws ScriptException{
		return caculate(script, null, sortMap, null);
	}
	
	/**
	 * 根据公式计算出值，根据传入的当前字段排序和编译对象map，避免多次编译，提高效率
	 * @param script
	 * @param sort
	 * @param sortMap
	 * @param compiledMap
	 * @return
	 * @throws ScriptException
	 */
	private String caculate(String script,String sort,Map<String, BigDecimal> sortMap,Map<String, CompiledScript> compiledMap) throws ScriptException{
		//公式替换中文括号及逗号
		script = script.replaceAll("（", "(").replaceAll("）", ")").replaceAll("，", ",");
		//替换成新公式，主要是把##替换为pm
		Pattern scriptPattern = Pattern.compile("#(\\w+)#");
		Matcher scriptMatcher = scriptPattern.matcher(script);
		StringBuffer stringBuffer = new StringBuffer();
		while (scriptMatcher.find()) {
			String g1 = scriptMatcher.group(1);
			scriptMatcher.appendReplacement(stringBuffer, "p"+g1+"m");
		}
		scriptMatcher.appendTail(stringBuffer);
		//首先使用正则匹配算法运算部分
		Pattern algPattern = Pattern.compile("\\((\\w*):([\\w,]+)\\)");
		Matcher algMatcher = algPattern.matcher(stringBuffer.toString());
		StringBuffer newSB = new StringBuffer();
		while (algMatcher.find()) {
			//算法名称
			String g1 = algMatcher.group(1);
			//参数列表
			String g2 = algMatcher.group(2);
			Double algResult = algorithm(g1, g2.split(","), sortMap);
			if (null == algResult) {
				return "存在空数据字段，请仔细检查！";
			}
			algMatcher.appendReplacement(newSB, String.valueOf(algResult));
		}
		algMatcher.appendTail(newSB);
		if (newSB.length()>0) {
			stringBuffer = newSB;
		}
		Object result = 0.00;
		ScriptEngine scriptEngine = new ScriptEngineManager().getEngineByName("javascript");
		Bindings bindings = scriptEngine.createBindings();
		//得到编译对象，首选从map中获取，如果已被编译，不用再次编译，节约资源
		//如果map中没有，说明未被编译过，这时再编译
		CompiledScript JSFunction = null;
		//说明已经被编译过
		/*if (null != compiledMap && compiledMap.containsKey(sort)) {
			JSFunction = compiledMap.get(sort);
		}else {
			//新建解析引擎
		}*/
		Compilable compilable = (Compilable) scriptEngine;
		JSFunction = compilable.compile(stringBuffer.toString());
		if (null != compiledMap) {
			compiledMap.put(sort, JSFunction);
		}
		//然后进行标准四则运算
		Pattern pattern = Pattern.compile("p(\\w+)m");
		Matcher matcher = pattern.matcher(stringBuffer.toString());
		while (matcher.find()) {
			String g2 = matcher.group(1);
			BigDecimal value = sortMap.get(g2);
			if (null == value || value.compareTo(BigDecimal.ZERO) == 0) {
				return result.toString();
			}
			bindings.put("p"+g2+"m", sortMap.get(g2));
		}
		result = JSFunction.eval(bindings);
		return String.format("%.2f", Double.parseDouble(result.toString()));
	}
	
	/**
	 * 刷新数据表中数据，重新计算需要计算的字段
	 * @param insData
	 * @return
	 */
	@Transactional(isolation = Isolation.DEFAULT,propagation = Propagation.REQUIRED,readOnly = false, rollbackFor = Exception.class)
	public String refreshTable(InsData insData){
		InsTable insTable = insTableService.get(insData.getTable().getId());
		//根据表id查找出所有data
		List<InsData> datas = dao.findList(insData);
		Map<String, CompiledScript> compiledMap = new HashMap<>();
		//对每一个data做计算操作
		try {
			//数值超过范围的参数集合
			Set<String> fieldSet = new HashSet<>();
			//数值超过范围的数据条数
			int count = 0;
			for (InsData data : datas) {
				//List<InsDataLink> dataLinks = insDataLinkDao.getByDataId(data.getId());
				List<InsDataLink> dataLinks = insDataLinkDao.getForRefresh(data);
				Map<String, BigDecimal> sortMap = getSortMap(dataLinks);
				boolean overRangeFlag = false;
				for (InsDataLink insDataLink : dataLinks) {
					InsField insField = insDataLink.getField();
					//说明该字段需要计算
					if ("2".equals(insField.getPreInput()) && !StringUtils.isEmpty(insField.getPreValues())) {
						String result = caculate(insField.getPreValues(), String.valueOf(insField.getSort()), sortMap , compiledMap);
						if ("存在空数据字段，请仔细检查！".equals(result)) {
							return result;
						}
						insDataLink.setValue(result);
						//校验数值范围
						if ("1".equals(insField.getEnableNumberRange()) && validNumberRange(insField, insDataLink.getValue())) {
							//设置标记
							insDataLink.setOverRange("1");
							fieldSet.add(insField.getName()+" ");
							overRangeFlag = true;
						}else{
							insDataLink.setOverRange("0");
						}
						if (!StringUtils.isEmpty(insDataLink.getId())) {
							insDataLink.preUpdate();
							insDataLinkDao.refresh(insDataLink);
						}else{
							insDataLink.preInsert();
							insDataLink.setTable(insField.getTable());
							insDataLink.setData(data);
							insDataLinkDao.insert(insDataLink);
						}
					}
				}
				if (overRangeFlag) {
					count++;
				}
			}
			//发送邮件
			if (count > 0) {
				StringBuffer overRangeFields = new StringBuffer();
				for (String fieldName : fieldSet) {
					overRangeFields.append(fieldName+" ");
				}
				sendMailToUsers(insTable, overRangeFields.toString());
			}
		} catch (Exception e) {
			e.printStackTrace();
			return "表内计算失败！请仔细检查数据及公式！";
		}
		return "success";
	}
	
	/**
	 * 构建排序和值的映射map，替换公式参数
	 * @param datas
	 * @return
	 */
	private Map<String, BigDecimal> getSortMap(List<InsDataLink> datas) throws Exception{
		//建立sort和field对象的映射
		Map<String, BigDecimal> sortMap = new HashMap<>();
		for (InsDataLink insDataLink : datas) {
			String value = insDataLink.getValue();
			if (StringUtils.isEmpty(value)) {
				continue;
			}
			String type = insDataLink.getField().getType();
			String sort = String.valueOf(insDataLink.getField().getSort());
			switch (type) {
			case "2":
				sortMap.put(sort, new BigDecimal(value));
				break;
			//年月日时分秒
			case "3":
				DateFormat df1 = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");
				Date date1 = df1.parse(value);
				sortMap.put(sort, new BigDecimal(date1.getTime()/1000));
				break;
			//年月日
			case "4":
				DateFormat df2 = new SimpleDateFormat("yyyy年MM月dd日");
				Date date2 = df2.parse(value);
				sortMap.put(sort, new BigDecimal(date2.getTime()/1000));
				break;
			//年月
			case "5":
				DateFormat df3 = new SimpleDateFormat("yyyy年MM月dd日");
				Date date3 = df3.parse(value);
				sortMap.put(sort, new BigDecimal(date3.getTime()/1000));
				break;
			default:
				break;
			}
		}
		return sortMap;
	}
	
	private Double algorithm(String alg,String[] param,Map<String, BigDecimal> sortMap){
		alg = alg.toLowerCase();
		//遍历param数组，得到double类型的参数数组
		double[] doubleParam = new double[param.length];
		for (int i = 0; i < param.length; i++) {
			BigDecimal bigDecimal = sortMap.get(param[i].replaceAll("p", "").replaceAll("m", ""));
			if (null == bigDecimal) {
				return null;
			}
			doubleParam[i] = bigDecimal.doubleValue();
		}
		double result = 0.0;
		//sum求和,avg平均数,mode众数,med中位数,mid中列数,rag极差,var方差,aad绝对平均偏差,mad中位数绝对偏差,sd标准差
		switch (alg) {
			//求和
			case "sum":
				result = MathUtil.getSum(doubleParam);
				break;
			//平均
			case "avg":
				result = MathUtil.getMean(doubleParam);
				break;
			//众数
			case "mode":
				result = MathUtil.getMode(doubleParam);
				break;
			//中位数
			case "med":
				result = MathUtil.getMedian(doubleParam);
				break;
			//中列数
			case "mid":
				result = MathUtil.getMidrange(doubleParam);
				break;
			//极差
			case "qtl":
				result = MathUtil.getRange(doubleParam);
				break;
			//方差
			case "var":
				result = MathUtil.getVariance(doubleParam);
				break;
			//绝对平均偏差
			case "aad":
				result = MathUtil.getAbsoluteAverageDeviation(doubleParam);
				break;
			//中位数绝对偏差
			case "mad":
				result = MathUtil.getMedianAbsoluteDeviation(doubleParam);
				break;
			//标准差
			case "sd":
				result = MathUtil.getStandardDevition(doubleParam);
				break;
			default:
				break;
		}
		return result;
	}
	
	/**
	 * 给设定的用户发送预警邮件
	 * @param insTable
	 * @param overRangeFields
	 */
	private void sendMailToUsers(InsTable insTable,String overRangeFields){
		//给设置的收件人发送邮件
		if (!StringUtils.isEmpty(insTable.getReceiveIds())) {
			String[] idArray = insTable.getReceiveIds().split(",");
			List<User> users = systemService.getByReceiveIds(idArray);
			if (null != users && users.size() > 0) {
				for (User user : users) {
					if (!StringUtils.isEmpty(user.getEmail())) {
						StringBuffer sb = new StringBuffer();
						sb.append(user.getName());
						sb.append(",您填报的数据表：<"+insTable.getName());
						sb.append(">中，参数：<"+overRangeFields+">超出设定范围，请查看!");
						MailUtil.SendMail(user.getEmail(), "数据表：<"+insTable.getName()+">有参数超出范围", sb.toString());
					}
				}
			}
		}
	}
}